﻿// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================

using System.ServiceModel;

#if SILVERLIGHT
using System.Security.Cryptography;
#else
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Security.Cryptography;
#endif

namespace SL.IdentityModel.Protocols.WSTrust
{
	/// <summary>
	/// This class contains the information for making a WS-Trust issue, RequestSecurityToken
	/// </summary>
	public class RequestSecurityToken
	{
		public const int SymmetricKeySizeInBitsConstant = 256;
		public const string DefaultKeyType = WSTrust13Constants.KeyTypes.Symmetric;

#if SILVERLIGHT
		private static RandomNumberGenerator _rng = new RNGCryptoServiceProvider();
#endif

        private EndpointAddress _appliesTo = null;
		private byte[] _entropyBytes = null;
		private int? _keySizeInBits = null;
		private string _keyType = null;

		/// <summary>
		/// Endpoint value to include in the AppliesTo element of the request
		/// </summary>
		public EndpointAddress AppliesTo
		{
			get { return _appliesTo; }
			set { _appliesTo = value; }
		}

		/// <summary>
		/// Entropy for the request if key is symmetric key type
		/// </summary>
		public byte[] EntropyBytes
		{
			get { return _entropyBytes; }
			set { _entropyBytes = value; }
		}

		/// <summary>
		/// This defines the KeySize element inside the RequestSecurityToken message
		/// It is specified in bits.
		/// </summary>
		public int? KeySizeInBits
		{
			get { return _keySizeInBits; }
			set { _keySizeInBits = value; }
		}

		/// <summary>
		/// Requested proof key type
		/// </summary>
		public string KeyType
		{
			get { return _keyType; }
		}

		/// <summary>
		/// Request type
		/// </summary>
		public string RequestType
		{
			get { return requestType; }
			protected set { requestType = value; }
		}
		private string requestType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue";

		public RequestSecurityToken()
			: this(DefaultKeyType)
		{
		}

		public RequestSecurityToken(string keyType)
		{
			_keyType = keyType;

			// Compute entropy
			if (string.Equals(_keyType, WSTrust13Constants.KeyTypes.Symmetric))
			{
				KeySizeInBits = SymmetricKeySizeInBitsConstant;

#if SILVERLIGHT
				_entropyBytes = new byte[SymmetricKeySizeInBitsConstant / 8];
				_rng.GetBytes(_entropyBytes);
#else
                _entropyBytes = CryptographicBuffer.GenerateRandom(SymmetricKeySizeInBitsConstant / 8).ToArray();
#endif
            }
		}
	}
}
